
#import "SJNetworking.h"
#import <Reachability/Reachability.h>
#import <AFNetworking/AFNetworkReachabilityManager.h>
#import <AFNetworking/AFNetworkActivityIndicatorManager.h>

NS_ASSUME_NONNULL_BEGIN
@interface SJNetworking ()
@property (nonatomic, strong, readonly) Reachability *reachability;
@end

@implementation SJNetworking

+ (instancetype)shared {
    static id _instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [self new];
    });
    return _instance;
}

- (instancetype)init {
    self = [super init];
    if ( !self ) return nil;
    _debug = YES;
    _reachability = [Reachability reachabilityForInternetConnection];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_reachabilityChangedNotification) name:kReachabilityChangedNotification object:_reachability];
    [_reachability startNotifier];

    /// 设置请求超时时间
    self.requestSerializer.timeoutInterval = 20;
    
    /// 打开状态栏的等待菊花
    [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
    
    /// Cache
    /// 设置相应的缓存策略：此处选择不用加载也可以使用自动缓存
    /// [注：只有get方法才能用此缓存策略，NSURLRequestReturnCacheDataDontLoad]
    self.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
    
    /// 设置请求服务器数类型式为 json
    self.requestSerializer = [AFJSONRequestSerializer serializer];
    
    /// 设置响应数据的基本类型
    self.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"application/xml", @"application/hal+json", @"text/json", @"text/javascript",@"text/html",@"text/css",@"text/xml",@"text/plain", @"application/javascript", @"image/*", nil];

    /// 设置返回数据类型为 json, 分别设置请求以及相应的序列化器
    self.responseSerializer = [AFJSONResponseSerializer serializer];
    /// 这里是去掉了键值对里 空对象的键值
    ((AFJSONResponseSerializer *)self.responseSerializer).removesKeysWithNullValues = YES;
    
    /// https
    self.securityPolicy = [AFSecurityPolicy defaultPolicy];
    self.securityPolicy.allowInvalidCertificates = YES;
    self.securityPolicy.validatesDomainName = NO;
    return self;
}
- (void)dealloc {
    [_reachability stopNotifier];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kReachabilityChangedNotification object:_reachability];
}

#pragma mark
- (NSURLSessionTask *)requestWithType:(SJNetworkingRequestType)type
                               URLStr:(NSString *)URLStr
                           parameters:(NSDictionary *__nullable)parameters
                           completion:(void (^ __nullable)(id _Nullable, NSError * _Nullable))block {
    
    if ( 0 == URLStr.length ) {
        NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:-1 userInfo:@{@"msg":@"传入的URL为空!"}];
        if ( block ) block(nil, error);
        return nil;
    }
    
    NSURLSessionTask *sessionTask = nil;
    
    __weak typeof(self) _self = self;
    void(^networkingSuccessBlock)(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) = ^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        __strong typeof(_self) self = _self;
        if ( !self ) return;
        if ( block ) block(responseObject, nil);
    };
    
    void(^networkingFailureBlock)(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) = ^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        __strong typeof(_self) self = _self;
        if ( !self ) return;
        if ( block )  block(nil, error);
    };
    
    NSString *requestType;
    switch (type) {
        case SJNetworkingRequestType_GET: {
            requestType = @"Get";
            sessionTask = [self GET:URLStr
                         parameters:parameters
                           progress:nil
                            success:networkingSuccessBlock
                            failure:networkingFailureBlock];
            
        }
            break;
        case SJNetworkingRequestType_POST: {
            requestType = @"Post";
            sessionTask = [self POST:URLStr
                           parameters:parameters
                             progress:nil
                              success:networkingSuccessBlock
                              failure:networkingFailureBlock];
        }
            break;
        default:
            NSLog(@"请求类型不支持 %s - %d", __FILE__, __LINE__);
            break;
    }
    
    if ( _debug ) {
        NSLog(@"******************** 请求参数 ***************************"); \
        NSLog(@"\n请求头: %@\n请求方式: %@\n请求URL: %@\n请求param: %@\n\n",self.requestSerializer.HTTPRequestHeaders, requestType, URLStr, parameters); \
        NSLog(@"******************************************************");
    }
    return sessionTask;
}

#pragma mark
- (void)_reachabilityChangedNotification {
    _networkingStatus = (NSInteger)[self.reachability currentReachabilityStatus];
}

@end
NS_ASSUME_NONNULL_END
